﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace VechileABS
{
    public class SocketHelper
    {
        private string _ip = string.Empty;
        private int _port = 0;
        private Socket _socket = null;
        Thread threadRec;
        bool isStop = false;
        bool isOnline = false;

        public string StrRecCode;
        public string StrRecMsg;
        public string LogPath;
        public bool hasErrorCode;
        public string errorMsg;

        public delegate void SendEventHandler(byte[] data);
        public event SendEventHandler SendInfor;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ip">连接服务器的IP</param>
        /// <param name="port">连接服务器的端口</param>
        public SocketHelper(string ip, int port)
        {
            this._ip = ip;
            this._port = port;
            StrRecCode = "";
            StrRecMsg = "";
        }


        /// <summary>
        /// 开启服务,连接服务端
        /// </summary>
        public bool StartClient()
        {
            try
            {
                //1.0 实例化套接字(IP4寻址地址,流式传输,TCP协议)
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //2.0 创建IP对象
                IPAddress address = IPAddress.Parse(_ip);
                //3.0 创建网络端口包括ip和端口
                IPEndPoint endPoint = new IPEndPoint(address, _port);
                //4.0 建立连接
                _socket.Connect(endPoint);

                isOnline = _socket.Connected;

                threadRec = new Thread(RecMsg);
                threadRec.IsBackground = true;
                threadRec.Start();
                return true;

            }
            catch (Exception)
            {
                _socket.Shutdown(SocketShutdown.Both);
                _socket.Close();
                return false;
            }
        }

        public void CloseClient()
        {
            try
            {
                if (!isOnline)
                {
                    return;
                }
                isStop = true;
                Thread.Sleep(1000);
                _socket.Close();
                threadRec.Abort();
                threadRec.DisableComObjectEagerCleanup();
            }
            catch (Exception ex)
            {
                _socket.Shutdown(SocketShutdown.Both);
                _socket.Close();
            }
        }

        public void SendMessage(byte[] buf)
        {
            try
            {
                if (!isOnline)
                {
                    return;
                }
                _socket.Send(buf);
                SaveLog(DateTime.Now.ToString("d"), DateTime.Now.ToString("G") + "【Send】" + ByteToString(buf));
            }
            catch (Exception ex)
            {
                _socket.Shutdown(SocketShutdown.Both);
                _socket.Close();
            }
        }

        public string DataCheck(string checkPart)//校验位
        {
            string checkValues = "";
            if (!string.IsNullOrEmpty(checkPart))
            {
                char[] ch = checkPart.ToArray();
                int sum = 0;
                foreach (var b in ch)
                {
                    sum += int.Parse(b.ToString());
                }

                sum = sum % 255;//模FF
                sum = ~sum + 1;//取反+1
                checkValues = Convert.ToString(sum, 16);

            }

            return checkValues;

        }

        private void RecMsg()
        {
            try
            {
                while (true)
                {
                    if (isStop)
                    {
                        break;
                    }
                    byte[] recMessage = new byte[1024];
         
                    int length = _socket.Receive(recMessage);
                    if (length > 0)
                    {
                        StrRecMsg = Encoding.Default.GetString(recMessage, 0, length);
                        byte[] buf = new byte[length];
                        Array.Copy(recMessage, buf, length);
                        SendInfor(buf);
                        SaveLog(DateTime.Now.ToString("d"), DateTime.Now.ToString("G") + "【Receive】" + ByteToString(buf));
                    }

                }
            }
            catch (System.Exception ex)
            {
                SaveLog(DateTime.Now.ToString("d"), DateTime.Now.ToString("G") + "【Error】" + ex.Message);
            }

        }

        private string ByteToString(byte[] data)
        {
            string msg = "";
            if (data.Length > 0)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    msg += string.Format("{0:X}", data[i]).PadLeft(2, '0') + " ";
                }
                return msg;
            }
            return msg;
        }

        private void SaveLog(string logName, string message)
        {
            try
            {
                StringBuilder path = new StringBuilder();
                path.Append(System.Windows.Forms.Application.StartupPath + "\\log\\");
                if (!Directory.Exists(path.ToString()))
                {
                    Directory.CreateDirectory(path.ToString());
                }
                path.Append(logName);
                path.Append(@".log");
                if (File.Exists(path.ToString()))
                {
                    StreamWriter sr = File.AppendText(path.ToString());
                    sr.WriteLine(message);
                    sr.Close();
                }
                else
                {
                    StreamWriter sr = File.CreateText(path.ToString());
                    sr.WriteLine(message);
                    sr.Close();
                }

            }
            catch (Exception)
            {

            }

        }

    }
}
